package com.internetCafes.spms.web.certificate.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.internetCafes.spms.common.CertificateTypeConstants;
import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.core.exception.RRExceptionCodeEnum;
import com.internetCafes.spms.core.generic.GenericDao;
import com.internetCafes.spms.core.generic.GenericServiceImpl;
import com.internetCafes.spms.core.model.pageModel.DataGrid;
import com.internetCafes.spms.web.certificate.dao.CertificateInfoMapper;
import com.internetCafes.spms.web.certificate.model.dto.transaction.BorrowOutReturnBatchDTO;
import com.internetCafes.spms.web.certificate.model.vo.CertificateHoldersVO;
import com.internetCafes.spms.web.certificate.entity.CertiTransactionInfo;
import com.internetCafes.spms.web.certificate.entity.CertificateInfo;
import com.internetCafes.spms.web.certificate.entity.CertificateRenewalInfo;
import com.internetCafes.spms.web.certificate.entity.EmployeeInfo;
import com.internetCafes.spms.web.certificate.service.CertiTransactionInfoService;
import com.internetCafes.spms.web.certificate.service.CertificateInfoService;
import com.internetCafes.spms.web.certificate.service.CertificateRenewalInfoService;
import com.internetCafes.spms.web.certificate.service.EmployeeInfoService;
import com.internetCafes.spms.web.certificate.vo.CertificateInfoVo;
import com.internetCafes.spms.web.certificate.vo.CollectInfo;
import com.internetCafes.spms.web.customer.service.user.IEntUserInfoService;
import com.internetCafes.spms.web.sys.model.ConfInfo;
import com.internetCafes.spms.web.sys.model.ResourceInfo;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.ConfInfoService;
import com.internetCafes.spms.web.sys.service.ResourceInfoService;
import com.internetCafes.spms.web.tenant.model.TenantDeptInfo;
import com.internetCafes.spms.web.tenant.service.TenantDeptInfoService;
import com.sms.common.util.hutool.core.util.ObjectUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;


/**
 * 证书信息表 CertificateInfoService 实现类
 *
 * @author Sunny
 */
@Service("certificateInfoService")
public class CertificateInfoServiceImpl extends GenericServiceImpl<CertificateInfo, Long> implements CertificateInfoService {

    @Autowired
    private CertificateInfoMapper certificateInfoMapper;

    @Autowired
    private EmployeeInfoService employeeInfoService;

    @Autowired
    private ResourceInfoService resourceInfoService;

    @Autowired
    private CertiTransactionInfoService certiTransactionInfoService;

    @Autowired
    private TenantDeptInfoService tenantDeptInfoService;

    @Autowired
    private CertificateRenewalInfoService certificateRenewalInfoService;

    @Autowired
    private ConfInfoService confInfoService;

    @Autowired
    private IEntUserInfoService entUserInfoService;

    @Value("${system.upload.pic}")
    private String picPath;

    private static Logger logger = Logger.getLogger(CertificateInfoServiceImpl.class);

    @Override
    public boolean deleteById(Long id) {
        CertificateInfo certificate = findById(id);
        if (ObjectUtil.isNull(certificate)) {
            throw new RRException(RRExceptionCodeEnum.DATA_NOT_EXIST);
        }
        if (CommonConstants.CertificateStatus.DELETE != certificate.getStatus()) {
            throw new RRException(RRExceptionCodeEnum.CERTIFICATE_STATUS_NOT_VOID);
        }
        // 删除证书的相关数据
        certiTransactionInfoService.deleteByCertificateId(id);
        certificateRenewalInfoService.deleteByCertificateId(id);
        return delete(id) > 0;
    }

    /**
     * 获取所有持有的证书列表
     */
    @Override
    public List<CertificateInfo> getAllHandlerCerts() {
        Map<String, Object> params = new HashMap<>();
        params.put("statuses", CommonConstants.CertificateStatus.EXCEPT_DELETE);
        return certificateInfoMapper.selectByParams(params);
    }

    /**
     * 批量还回押证的证书
     *
     * @param dto 请求参数
     * @author Zj
     */
    @Override
    public void borrowOutReturnBatch(BorrowOutReturnBatchDTO dto) {
        /*
         *  1-获取证书以及证书流转记录详情=sql对证书情况进行判断过滤
         *  3-证书借出记录修改 1、更新内容 完成状态修改 归还时间修改
         *  4-证书还回记录添加
         *  5-证书状态修改 证书状态为空闲
         *  有修改权限，并且是借出人，或者借出人的上级
         */
        if (CollectionUtils.isEmpty(dto.getIds())) {
            throw new RRException("请选择证书");
        }
        // 1.2-获取证书流转记录列表
        List<CertiTransactionInfo> transactionInfos =
                certiTransactionInfoService.getWarrantTransactionRecordByCertificateIds(dto.getIds());

        UserInfo userInfo = ShiroUtils.getUserEntity();
        List<Long> transactionIds = new ArrayList<>();
        List<Long> createByUserIdList = new ArrayList<>();
        boolean allOwnFlag = true; // 全部数据是自己的标签
        for (CertiTransactionInfo transactionInfoPo : transactionInfos) {
            transactionIds.add(transactionInfoPo.getId());
            createByUserIdList.add(transactionInfoPo.getCreateBy());
            if (!userInfo.getId().equals(transactionInfoPo.getCreateBy())) {
                allOwnFlag = false;
            }
        }

        if (CollectionUtils.isEmpty(transactionIds)) {
            return;
        }

        // 有修改权限，并且是挂出人，或者挂出人的上级
        if (!allOwnFlag) {
            if (entUserInfoService.isLowerLevelUserIdListOfManagerUser(createByUserIdList, userInfo)) {
                throw new RRException(RRExceptionCodeEnum.NO_AUTHORITY);
            }
        }

        HashMap<String, Object> params = new HashMap<>();
        params.put("ids", transactionIds);
        params.put("statusTag", CommonConstants.CertiTransactionStatusTags.COMPLETE.getTag());
        params.put("transactionEndTime", dto.getTransactionTime());
        certiTransactionInfoService.updateTransactionBatch(params);

        Date currentTime = new Date();
        Long currentCreateBy = userInfo.getId();

        // 3-证书还回记录封装
        List<CertiTransactionInfo> transactionReturnDOs = transactionInfos.stream()
                .map(transactionOutRecord -> {
                    CertiTransactionInfo transactionReturnDO = new CertiTransactionInfo();
                    BeanUtils.copyProperties(transactionOutRecord, transactionReturnDO);
                    transactionReturnDO.transactionReturnInfoCopy(transactionOutRecord,
                            currentCreateBy, currentTime, dto.getRemark(), dto.getTransactionTime());
                    return transactionReturnDO;
                })
                .collect(Collectors.toList());
        certiTransactionInfoService.saveBatch(transactionReturnDOs);

        // 4-批量更新证书状态以及还回时间
        transactionInfos.forEach(transactionOutRecord -> {
            CertificateInfo certificateInfoUpdateDO = new CertificateInfo(
                    transactionOutRecord.getCertificateId(), transactionOutRecord.getFromDeptId(),
                    transactionOutRecord.getFromDeptName(), transactionOutRecord.getFromUserId(),
                    transactionOutRecord.getFromUserName(), transactionOutRecord.getFromUserMobile(),
                    CommonConstants.CertificateStatus.NO_USE
            );
            update(certificateInfoUpdateDO);
        });
    }

    /**
     * 更具证书id列表批量更新证书信息
     *
     * @param param ids列表 需要修改的信息
     * @author Zj
     */
    @Override
    public void updateCertificateInfoBatch(Map<String, Object> param) {
        certificateInfoMapper.updateCertificateInfoBatch(param);
    }

    /**
     * 根据证书编号列表获取证书信息
     *
     * @param certificateNos 证书编号
     * @return 证书信息
     * @author Zj
     */
    @Override
    public List<CertificateInfo> certificateInfosByNos(List<String> certificateNos) {
        Map<String, Object> param = new HashMap<>();
        param.put("certificateNos", certificateNos);
        return certificateInfoMapper.certificateInfosByNos(param);
    }

    /**
     * 获取持证人列表
     *
     * @return 人员列表
     * @author Zj
     */
    @Override
    public List<CertificateHoldersVO> certificateHolders() {
        List<EmployeeInfo> employeeInfos = employeeInfoService.queryRepeat();
        return employeeInfos.stream()
                .map(employee -> new CertificateHoldersVO(employee.getId(), employee.getName(), employee.getIdCard()))
                .collect(Collectors.toList());
    }

    /**
     * 根据证书的id列表 更新最后的id
     *
     * @param certificateIds  证书id
     * @param finalEmployeeId 最终employee的id
     * @author Zheng
     */
    @Override
    public void updateEmployeeIdBatch(List<Long> certificateIds, Long finalEmployeeId) {
        Map<String, Object> params = new HashMap<>();
        params.put("certificateIds", certificateIds);
        params.put("finalEmployeeId", finalEmployeeId);
        certificateInfoMapper.updateEmployeeIdBatch(params);
    }

    /**
     * 通过身份证号获取相关证书数据
     *
     * @param idCards
     * @return 结果
     */
    @Override
    public List<CertificateInfoVo> selectInfoByIdCardsForRepeat(List<String> idCards) {
        Map<String, Object> params = new HashMap<>();
        params.put("idCards", idCards);
        return certificateInfoMapper.selectInfoByIdCardsForRepeat(params);
    }

    /**
     * 获取需要短信提醒的证书信息列表
     *
     * @param tenantIds 企业id
     * @return 证书信息列表
     * @author Zj
     */
    @Override
    public List<CertificateInfoVo> selectExpireInfo(List<Long> tenantIds) {
        Map<String, Object> params = new HashMap<>();
        params.put("tenantIds", tenantIds);
        return certificateInfoMapper.selectExpireInfo(params);
    }

    /**
     * 获取需要短信提醒的证书信息列表
     */
    /*@Override
    public List<CertificateInfoVo> selectExpireInfo() {
        return certificateInfoMapper.selectExpireInfo();
    }*/
    @Override
    public List<CertificateInfo> query(Map<String, Object> params) {
        return certificateInfoMapper.selectByParams(params);
    }

    @Override
    public CertificateInfo findById(Long id) {
        return certificateInfoMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<CertificateInfo> queryByIds(List<Long> ids) {
        Map<String, Object> params = new HashMap<>();
        params.put("ids", ids);
        return certificateInfoMapper.selectByParams(params);
    }

    @Override
    public List<CertificateInfo> page(Map<String, Object> params, int page, int rows) {
        params.put("page", page);
        params.put("rows", rows);
        return certificateInfoMapper.selectByParams(params);
    }

    @Override
    public long count(Map<String, Object> params) {
        return certificateInfoMapper.countByParams(params);
    }

    @Override
    public long countByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.countByJobParams(params);
    }

    @Override
    public CertificateInfo findFirst(Map<String, Object> params) {
        List<CertificateInfo> list = certificateInfoMapper.selectByParams(params);
        CertificateInfo certificateInfo = null;
        if (list != null && list.size() > 0) {
            certificateInfo = list.get(0);
        }
        return certificateInfo;
    }

    @Override
    public int save(CertificateInfo certificateInfo) {
        return certificateInfoMapper.insert(certificateInfo);
    }

    @Override
    public int save(CertificateInfoVo vo) {

        UserInfo u = ShiroUtils.getUserEntity();
        CertificateInfo c = new CertificateInfo();
        BeanUtils.copyProperties(vo, c);
        c.setCreateTime(new Date());
        c.setCreateBy(u.getId());

        EmployeeInfo e;
        if (vo.getCertificateType() != CommonConstants.CertificateType.SELF) {
            Map<String, Object> params = new HashMap<>();
            params.put("tenantId", u.getDeptId());
            params.put("idCard", vo.getIdCard());
            e = employeeInfoService.findFirst(params);
            if (e == null || vo.getIdCard().equals(CommonConstants.COMMON_ID_CARD)) {
                e = new EmployeeInfo();
                BeanUtils.copyProperties(vo, e);
                e.setType(vo.getCertificateType());
                e.setCreateTime(new Date());
                e.setCreateBy(ShiroUtils.getUserId());
                e.setTenantId(u.getDeptId());
                e.setType(CommonConstants.EmployeeInfoType.OTHER);
                e.setStatus(CommonConstants.CommonStatus.ENABLE);
                e.setEmployeeFlag(CommonConstants.CommonStatus.DISABLE);
                employeeInfoService.save(e);
            } else {
                e.setName(vo.getName());
                e.setIdCard(vo.getIdCard());
                e.setMobile(vo.getMobile());
                e.setAcademic(vo.getAcademic());
                employeeInfoService.update(e);
            }
        } else {
            e = employeeInfoService.findById(vo.getEmployeeId());
        }
        c.setEmployeeId(e.getId());

        TenantDeptInfo d;
        if (vo.getKeepUserId() == null || vo.getKeepUserId() == 0) {
            e = employeeInfoService.findById(u.getUserId());
            c.setKeepUserName(e.getName());
            c.setKeepUserId(e.getId());
            c.setKeepContactMobile(e.getMobile());
            c.setKeepDeptId(e.getDeptId());
            d = tenantDeptInfoService.findById(c.getKeepDeptId());
            c.setKeepDeptName(d.getDeptName());
        } else {
            e = employeeInfoService.findById(vo.getKeepUserId());
            c.setKeepUserName(e.getName());
            c.setKeepContactMobile(e.getMobile());
            d = tenantDeptInfoService.findById(c.getKeepDeptId());
            c.setKeepDeptName(d.getDeptName());
        }

        c.setOriKeepDeptId(c.getKeepDeptId());
        c.setOriKeepDeptName(c.getKeepDeptName());
        c.setOriKeepUserId(c.getKeepUserId());
        c.setOriKeepUserName(c.getKeepUserName());
        c.setOriKeepContactMobile(c.getKeepContactMobile());
        if (vo.getCertificateType() == CommonConstants.CertificateType.PartTime) {
            if (vo.getToDeptName() != null && vo.getToUserName() != null && vo.getToUserMobile() != null
                    && vo.getTransactionTime() != null && vo.getTransactionEndTime() != null
                    && vo.getAffiliationIncome() != null) {
                c.setStatus(CommonConstants.CertificateStatus.BORROW_OUT);
            } else {
                c.setStatus(CommonConstants.CertificateStatus.BORROW_IN);
            }
        } else {
            c.setStatus(CommonConstants.CertificateStatus.NO_USE);
        }
        save(c);
        if (vo.getCertificateType() == CommonConstants.CertificateType.PartTime) {
            CertiTransactionInfo ct = new CertiTransactionInfo(
                    u.getDeptId(),
                    c.getId(),
                    CommonConstants.CertiTransactionInfoType.BorrowIn,
                    vo.getBorrowOrgName(),
                    vo.getBorrowContact(),
                    vo.getBorrowContactMobile(),
                    c.getKeepDeptId(),
                    d.getDeptName(),
                    c.getKeepUserId(),
                    e.getName(),
                    e.getMobile(),
                    vo.getRemark(),
                    new Date()
            );
            ct.setAffiliationExpend(vo.getAffiliationExpend());
            ct.setAgencyFlag(vo.getAgencyFlag());
            ct.setAgencyName(vo.getAgencyName());
            ct.setAgencyFee(vo.getAgencyFee());
            ct.setFeeRemark(vo.getFeeRemark());
            ct.setPayFlag(vo.getPayFlag());
            ct.setPayTime(vo.getPayTime());
            ct.setTax(vo.getTax());
            ct.setCreateTime(new Date());
            ct.setCreateBy(ShiroUtils.getUserId());
            ct.setTransactionEndTime(vo.getBorrowEndTime());
            c.setStatus(CommonConstants.CertificateStatus.BORROW_IN);
            certiTransactionInfoService.save(ct);
            if (vo.getToDeptName() != null && vo.getToUserName() != null
                    && vo.getToUserMobile() != null && vo.getTransactionTime() != null && vo.getTransactionEndTime()
                    != null && vo.getAffiliationIncome() != null) {
                ct = new CertiTransactionInfo(
                        vo.getToDeptName(),
                        vo.getToUserName(),
                        vo.getToUserMobile(),
                        vo.getTransactionTime(),
                        vo.getTransactionEndTime()
                );
                if (vo.getBorrowOutRemark() != null) {
                    ct.setRemark(vo.getBorrowOutRemark());
                }
                if (vo.getAffiliationIncome() != null) {
                    ct.setAffiliationIncome(vo.getAffiliationIncome());
                }
                if (vo.getBorrowOutAgencyFee() != null) {
                    ct.setAgencyFee(vo.getBorrowOutAgencyFee());
                }
                ct.setOtherFee(vo.getOtherFee());
                if (vo.getBorrowOutFeeRemark() != null) {
                    ct.setFeeRemark(vo.getBorrowOutFeeRemark());
                }
                if (vo.getBorrowOutPayFlag() != null) {
                    ct.setPayFlag(vo.getBorrowOutPayFlag());
                }
                if (vo.getBorrowOutPayTime() != null) {
                    ct.setPayTime(vo.getBorrowOutPayTime());
                }
                if (vo.getBorrowOutTax() != null) {
                    ct.setTax(vo.getBorrowOutTax());
                }
                ct.setType(CommonConstants.CertiTransactionInfoType.BorrowOut);
                ct.setTenantId(u.getDeptId());
                ct.setCertificateId(c.getId());
                ct.setFromDeptId(c.getKeepDeptId());
                ct.setFromDeptName(c.getKeepDeptName());
                ct.setFromUserId(c.getKeepUserId());
                ct.setFromUserName(c.getKeepUserName());
                ct.setFromUserMobile(c.getKeepContactMobile());
                certiTransactionInfoService.save(ct);
            }
        }
        saveResourceInfo(u, vo, c);
        return 0;
    }

    @Override
    public int saveBatch(List<CertificateInfo> certificateInfoList) {
        return certificateInfoMapper.insertBatch(certificateInfoList);
    }

    @Override
    public int saveSelective(CertificateInfo certificateInfo) {
        return certificateInfoMapper.insertSelective(certificateInfo);
    }

    @Override
    public int update(CertificateInfoVo vo) {
        CertificateInfo _c = findById(vo.getId());
        if (_c == null) {
            throw new RRException("证书信息不存在，请联系管理员");
        }

        UserInfo u = ShiroUtils.getUserEntity();
        CertificateInfo c = new CertificateInfo();
        BeanUtils.copyProperties(vo, c);
        c.setUpdateTime(new Date());
        c.setUpdateBy(u.getId());
        if (vo.getKeepUserId() == null || vo.getKeepUserId() == 0) {
            EmployeeInfo e = employeeInfoService.findById(u.getUserId());
            c.setKeepUserName(e.getName());
            c.setKeepUserId(e.getId());
            c.setKeepContactMobile(e.getMobile());
            c.setKeepDeptId(e.getDeptId());
            TenantDeptInfo d = tenantDeptInfoService.findById(c.getKeepDeptId());
            c.setKeepDeptName(d.getDeptName());
        } else {
            EmployeeInfo e = employeeInfoService.findById(vo.getKeepUserId());
            c.setKeepUserName(e.getName());
            c.setKeepContactMobile(e.getMobile());
            TenantDeptInfo d = tenantDeptInfoService.findById(c.getKeepDeptId());
            c.setKeepDeptName(d.getDeptName());
        }
        update(c);

        EmployeeInfo e;
        if (vo.getCertificateType() != CommonConstants.CertificateType.SELF) {
            Map<String, Object> params = new HashMap<>();
            params.put("tenantId", u.getDeptId());
            params.put("id", c.getEmployeeId());
            e = employeeInfoService.findFirst(params);
            e.setName(vo.getName());
            e.setIdCard(vo.getIdCard());
            e.setMobile(vo.getMobile());
            e.setAcademic(vo.getAcademic());
            employeeInfoService.update(e);
        } else {
            e = employeeInfoService.findById(vo.getEmployeeId());
        }
        if (vo.getCertificateType() == CommonConstants.CertificateType.PartTime) {
            TenantDeptInfo d = tenantDeptInfoService.findById(c.getKeepDeptId());
            CertiTransactionInfo ct = new CertiTransactionInfo(
                    u.getDeptId(),
                    c.getId(),
                    CommonConstants.CertiTransactionInfoType.BorrowIn,
                    vo.getBorrowOrgName(),
                    vo.getBorrowContact(),
                    vo.getBorrowContactMobile(),
                    c.getKeepDeptId(),
                    d.getDeptName(),
                    c.getKeepUserId(),
                    e.getName(),
                    e.getMobile(),
                    vo.getRemark(),
                    new Date()
            );
            ct.setAffiliationExpend(vo.getAffiliationExpend());
            ct.setAgencyFlag(vo.getAgencyFlag());
            ct.setAgencyName(vo.getAgencyName());
            ct.setAgencyFee(vo.getAgencyFee());
            ct.setFeeRemark(vo.getFeeRemark());
            ct.setPayFlag(vo.getPayFlag());
            ct.setPayTime(vo.getPayTime());
            ct.setTax(vo.getTax());
            certiTransactionInfoService.update(ct);
        }

        saveResourceInfo(u, vo, c);

        return 0;
    }


    /**
     * 保存资源信息
     *
     * @param u
     * @param vo
     * @param c
     */
    private void saveResourceInfo(UserInfo u, CertificateInfoVo vo, CertificateInfo c) {
        Map<String, Object> params;
        if (StringUtils.isNotBlank(vo.getCertiPic()) && vo.getCertiPic().split(",").length > 0) {
            params = new HashMap<>();
            params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Certi);
            params.put("moduleId", c.getId());
            resourceInfoService.deleteByModuleAndUserId(params);
            String[] certiPics = vo.getCertiPic().split(",");
            for (String certiPic : certiPics) {
                ResourceInfo r = new ResourceInfo(u.getId(), CommonConstants.ResourceInfo_PIC_Certi, c.getId(), "pic" + File.separator + certiPic);
                resourceInfoService.save(r);
            }
        }

        if (StringUtils.isNotBlank(vo.getConstractPic()) && vo.getConstractPic().split(",").length > 0) {
            params = new HashMap<>();
            params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Constrat);
            params.put("moduleId", c.getId());
            resourceInfoService.deleteByModuleAndUserId(params);
            String[] constractPics = vo.getConstractPic().split(",");
            for (String constractPic : constractPics) {
                ResourceInfo r = new ResourceInfo(u.getId(), CommonConstants.ResourceInfo_PIC_Constrat, c.getId(), "pic" + File.separator + constractPic);
                resourceInfoService.save(r);
            }
        }

        if (StringUtils.isNotBlank(vo.getPayPic()) && vo.getPayPic().split(",").length > 0) {
            params = new HashMap<>();
            params.put("moduleCode", CommonConstants.ResourceInfo_PIC_Pay);
            params.put("moduleId", c.getId());
            resourceInfoService.deleteByModuleAndUserId(params);
            String[] payPics = vo.getPayPic().split(",");
            for (String payPic : payPics) {
                ResourceInfo r = new ResourceInfo(u.getId(), CommonConstants.ResourceInfo_PIC_Pay, c.getId(), "pic" + File.separator + payPic);
                resourceInfoService.save(r);
            }
        }
    }

    @Override
    public int update(CertificateInfo certificateInfo) {
        return certificateInfoMapper.updateByPrimaryKey(certificateInfo);
    }

    @Override
    public int updateSelective(CertificateInfo certificateInfo) {
        return certificateInfoMapper.updateByPrimaryKeySelective(certificateInfo);
    }

    @Override
    public int delete(Long id) {
        return certificateInfoMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int deleteBatch(List<Long> ids) {
        return certificateInfoMapper.deleteBatchByPrimaryKey(ids);
    }

    @Override
    public void deleteBatch(Long[] ids) {
        if (ids != null && ids.length > 0) {
            for (Long id : ids) {
                delete(id);
            }
        }
    }

    @Override
    public GenericDao<CertificateInfo, Long> getDao() {
        return certificateInfoMapper;
    }

    /**
     * DataGrid
     */
    public DataGrid dataGrid2(Map<String, Object> params, int pageNo, int pageSize) {

        params.put("page", (pageNo - 1 < 0 ? -1 : pageNo - 1) * pageSize);
        params.put("rows", pageSize);
//        PageHelper.startPage(pageNo,pageSize);
        List<CertificateInfoVo> certificateInfoList = certificateInfoMapper.selectByJobParams(params);
        PageInfo<CertificateInfoVo> pageInfo = new PageInfo<>(certificateInfoMapper.selectByJobParams(params));

        long count = certificateInfoMapper.countByJobParams(params);
        return new DataGrid(certificateInfoList, count, pageSize, pageNo);

    }

    /**
     * DataGrid
     */
    @Override
    public DataGrid dataGrid(Map<String, Object> params, int pageNo, int pageSize) {

//        params.put("page", (pageNo - 1 < 0 ? -1 : pageNo - 1) * pageSize);
//        params.put("rows", pageSize);
        PageHelper.startPage(pageNo, pageSize);
//        List<CertificateInfoVo> certificateInfoList = certificateInfoMapper.selectByJobParams(params);
        PageInfo<CertificateInfoVo> pageInfo = new PageInfo<>(certificateInfoMapper.selectByJobParams(params));

//        long count = certificateInfoMapper.countByJobParams(params);
        return new DataGrid(pageInfo.getList(), pageInfo.getTotal(), pageSize, pageNo);

    }

    @Override
    public List<CertificateInfoVo> selectByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.selectByJobParams(params);
    }

    public boolean getExistFlag(String certificateNo, String idCard, String profession) {
        Map<String, Object> params = new HashMap<>();
        params.put("certificateNo", certificateNo);
        List<CertificateInfo> certificateInfoList = query(params);
        if (!certificateNo.startsWith("水木石") && certificateInfoList.size() > 0) {
            CertificateInfo certificateInfo = CollectionUtil.getFirst(certificateInfoList);

            if (CommonConstants.CertificateStatus.DELETE == certificateInfo.getStatus()) {
                throw new RRException(RRExceptionCodeEnum.CERT_CERTIFICATE_HAS_TO_VOID);
            }
            return false;
        }

        /*Map<String, Object> params = new HashMap<>();
        params.put("statuses", CommonConstants.CertificateStatus.EXCEPT_DELETE);
        params.put("certificateNo", certificateNo);
        long count = count(params);
        if (count > 0 && !certificateNo.startsWith("水木石")) {
            return false;
        }*/
        params = new HashMap<>();
        params.put("idCard", idCard);
        EmployeeInfo e = employeeInfoService.findFirst(params);
        if (e != null && !idCard.equals(CommonConstants.COMMON_ID_CARD)) {
            params = new HashMap<>();
            params.put("profession", profession);
            params.put("employeeId", e.getId());
            long count = count(params);
            return count <= 1;
        }
        return true;
    }

    /**
     * 查询当前证书是否存在
     */
    public boolean getExistFlagV2(String certificateNo, String idCard, String profession) {
        Map<String, Object> params = new HashMap<>();
        params.put("statuses", CommonConstants.CertificateStatus.EXCEPT_DELETE);
        params.put("certificateNo", certificateNo);
        long count = count(params);
        if (count > 0 && !certificateNo.startsWith("水木石")) {
            return false;
        }
        params = new HashMap<>();
        params.put("idCard", idCard);
        EmployeeInfo e = employeeInfoService.findFirst(params);
        if (e != null && !idCard.equals(CommonConstants.COMMON_ID_CARD)) {
            params = new HashMap<>();
            params.put("profession", profession);
            params.put("employeeId", e.getId());
            count = count(params);
            return count <= 1;
        }
        return true;
    }

    @Override
    @Transactional
    public void updatePro(CertificateInfoVo vo) {
        CertificateInfo c = findById(vo.getId());
        UserInfo u = ShiroUtils.getUserEntity();
        if (c != null) {
            c.setReleaseTime(vo.getValidityStartTime());
            c.setValidityEndTime(vo.getValidityEndTime());
            update(c);
            saveResourceInfo(u, vo, c);
            CertificateRenewalInfo cc = new CertificateRenewalInfo(vo.getTenantId(), c.getId(), vo.getRenewalTime(), vo.getValidityStartTime(), vo.getValidityEndTime(), "无信息");
            certificateRenewalInfoService.save(cc);
        }
    }

    @Override
    public List<CollectInfo> collectAllByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.collectAllByJobParams(params);
    }

    @Override
    public List<CollectInfo> partJobCertByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.partJobCertByJobParams(params);
    }

    @Override
    public List<CollectInfo> passCertByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.passCertByJobParams(params);
    }

    @Override
    public List<CollectInfo> willPassCertByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.willPassCertByJobParams(params);
    }

    @Override
    public List<CollectInfo> bringCertByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.bringCertByJobParams(params);
    }

    @Override
    public List<CollectInfo> borrowCertByJobParams(Map<String, Object> params) {
        return certificateInfoMapper.borrowCertByJobParams(params);
    }

    @Override
    public String[] selectIdTypeByProfession(String profession) {
        String[] result = new String[2];
        Map<String, Object> params = new HashMap<>();
        params.put("value", profession);
        List<ConfInfo> idTypeList = confInfoService.query(params);
        if (CollectionUtils.isEmpty(idTypeList)) {
            return null;
        }
        if (idTypeList.size() == 1) {
            params = new HashMap<>();
            params.put("value", idTypeList.get(0).getType());
            List<ConfInfo> pIdList = confInfoService.query(params);
            result[0] = pIdList.get(0).getType();
            result[1] = idTypeList.get(0).getType();
            return result;
        }

        return setIdTypeFromMultipleChoice(idTypeList);
    }

    @Override
    public Integer updateCertificateIfNull(Map<String, Object> params) {
        int updateNumber = 0;
        boolean updateCertificateFlag = false;
        Map<String, Object> certificateParams = new HashMap<>();
        certificateParams.put("certificateNo", params.get("certificateNo"));
        List<CertificateInfo> certificateInfoList = certificateInfoMapper.selectByParams(certificateParams);
        for (CertificateInfo certificateInfo : certificateInfoList) {
            if (certificateInfo.getReleaseTime() == null && params.get("releaseTime") != null) {
                certificateInfo.setReleaseTime((Date) params.get("releaseTime"));
                updateCertificateFlag = true;
            }
            if (certificateInfo.getValidityEndTime() == null && params.get("validityEndTime") != null) {
                certificateInfo.setValidityEndTime((Date) params.get("validityEndTime"));
                updateCertificateFlag = true;
            }
            if (certificateInfo.getIdType() == null && params.get("idType") != null) {
                certificateInfo.setIdType((String) params.get("idType"));
                updateCertificateFlag = true;
            }
            if (updateCertificateFlag) {
                int influencedRecord = certificateInfoMapper.updateByPrimaryKey(certificateInfo);
                updateNumber += influencedRecord;
                logger.info("更新t_certificate_info表中" + influencedRecord + "条数据");
            }
            EmployeeInfo employeeInfo = employeeInfoService.findById(certificateInfo.getEmployeeId());
            if (employeeInfo.getIdCard() == null && params.get("idCard") != null) {
                employeeInfo.setIdCard((String) params.get("idCard"));
                int influencedRecord = employeeInfoService.update(employeeInfo);
                updateNumber += influencedRecord;
                logger.info("更新t_employee_info表中" + influencedRecord + "条数据");
            }
            Map<String, Object> resourceParams = new HashMap<>();
            resourceParams.put("moduleCode", CommonConstants.ResourceInfo_PIC_Certi);
            resourceParams.put("moduleId", certificateInfo.getId());
            List<ResourceInfo> resourceInfoList = resourceInfoService.query(resourceParams);
            if (CollectionUtils.isEmpty(resourceInfoList)) {
                UserInfo u = ShiroUtils.getUserEntity();
                ResourceInfo r = new ResourceInfo(u.getUserId(), CommonConstants.ResourceInfo_PIC_Certi, certificateInfo.getId(), "pic" + File.separator + params.get("fileName"));
                int influencedRecord = resourceInfoService.save(r);
                updateNumber += influencedRecord;
                logger.info("更新t_resource_info表中" + influencedRecord + "条数据");
            }

        }
        return updateNumber;
    }

    public String[] setIdTypeFromMultipleChoice(List<ConfInfo> idTypeList) {
        String[] result = new String[2];
        Map<String, Object> params = new HashMap<>();
        List<String> pIdTypeList = new ArrayList<>();
        for (ConfInfo confInfo : idTypeList) {
            params.put("value", confInfo.getType());
            List<ConfInfo> query = confInfoService.query(params);
            if (CollectionUtils.isNotEmpty(query)) {
                pIdTypeList.add(query.get(0).getType());
            }
        }

        pIdTypeList = new ArrayList<>(new HashSet<>(pIdTypeList));
        if (pIdTypeList.size() == 1) {
            switch (pIdTypeList.get(0)) {
                case CertificateTypeConstants.PIdTypeCode.TECHNICIAN:
                    result[1] = CertificateTypeConstants.IdType.TECHNICIAN_PROVINCE;
                    break;
                case CertificateTypeConstants.PIdTypeCode.PROFESSIONAL_TITLE:
                    result[1] = CertificateTypeConstants.IdType.INTERMEDIATE_ENGINEER;
                    break;
                case CertificateTypeConstants.PIdTypeCode.THREE_CATEGORIES_PERSONNEL:
                    result[1] = CertificateTypeConstants.IdType.HOUSE_THREE;
                    break;
                case CertificateTypeConstants.PIdTypeCode.REGISTERED_PERSONNEL:
                    result[1] = CertificateTypeConstants.IdType.SECOND_CLASS_ARCHITECT;
                    break;
                case CertificateTypeConstants.PIdTypeCode.ON_SITE_STAFF:
                    result[1] = CertificateTypeConstants.IdType.HOUSE_POST;
                    break;
                case CertificateTypeConstants.PIdTypeCode.SPECIAL_WORKERS:
                    result[1] = CertificateTypeConstants.IdType.HOUSE_SPECIAL;
                    break;
                case CertificateTypeConstants.PIdTypeCode.OTHERS:
                    result[1] = CertificateTypeConstants.IdType.OTHERS;
                    break;
            }
            result[0] = pIdTypeList.get(0);
            return result;
        }
        boolean includeRegisteredFlag = false;
        boolean includeProfessionalFlag = false;
        for (String pId : pIdTypeList) {
            if (pId.equals(CertificateTypeConstants.PIdTypeCode.REGISTERED_PERSONNEL)) {
                includeRegisteredFlag = true;
            }
            if (pId.equals(CertificateTypeConstants.PIdTypeCode.PROFESSIONAL_TITLE)) {
                includeProfessionalFlag = true;
            }
        }
        if (includeProfessionalFlag && includeRegisteredFlag) {
            result[0] = CertificateTypeConstants.PIdType.REGISTERED_PERSONNEL;
            result[1] = CertificateTypeConstants.IdType.SECOND_CLASS_ARCHITECT;
        }
        boolean includeTechnicianFlag = false;
        boolean includeSpecialFlag = false;
        for (String pId : pIdTypeList) {
            if (pId.equals(CertificateTypeConstants.PIdTypeCode.TECHNICIAN)) {
                includeTechnicianFlag = true;
            }
            if (pId.equals(CertificateTypeConstants.PIdTypeCode.SPECIAL_WORKERS)) {
                includeSpecialFlag = true;
            }
        }
        if (includeTechnicianFlag && includeSpecialFlag) {
            result[0] = CertificateTypeConstants.PIdType.SPECIAL_WORKERS;
            result[1] = CertificateTypeConstants.IdType.HOUSE_SPECIAL;
        }
        return result;
    }


    @Override
    public DataGrid selectByBalance(Map<String, Object> params, int pageNo, int pageSize) {
        params.put("page", (pageNo - 1 < 0 ? -1 : pageNo - 1) * pageSize);
        params.put("rows", pageSize);
        long count = certificateInfoMapper.countByJobParams(params);
        List<CertificateInfoVo> certificateInfoVos = certificateInfoMapper.selectCertificateBalance(params);
        return new DataGrid(certificateInfoVos, count, pageSize, pageNo);
    }

    @Override
    public List<CertificateInfoVo> selectByBalance(Map<String, Object> params) {
        return certificateInfoMapper.selectCertificateBalance(params);
    }

    @Override
    public List<CertificateInfoVo> getBalanceDetails(Map<String, Object> params) {
        return certificateInfoMapper.selectBalanceDetails(params);
    }

    @Override
    public Long countBalanceDetails(Map<String, Object> params) {
        return certificateInfoMapper.countBalanceDetails(params);
    }
}
